<?php
namespace App\Service;

use App\Entity\Comment;
use App\Entity\Money;
use App\Entity\MoneyLog;
use App\Entity\Task;
use App\Entity\User;
use App\Repository\CommentRepository;
use App\Repository\ConfigRepository;
use App\Repository\ShopTagRepository;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;

class TaskService extends ServiceEntityRepository
{

    public $shopTagRepository;
    public $configRepository;
    public $shopService;
    public $moneyService;
    public $announceService;
    public $commentService;


    public function __construct(
        ManagerRegistry $registry
        ,AnnounceService $announceService
        ,ShopService $shopService
        ,MoneyService $moneyService
        ,ShopTagRepository $shopTagRepository
        ,ConfigRepository $configRepository
        ,CommentService $commentService
    )
    {
        parent::__construct($registry, Task::class);
        $this->shopTagRepository = $shopTagRepository;
        $this->configRepository = $configRepository;
        $this->shopService = $shopService;
        $this->moneyService = $moneyService;
        $this->announceService = $announceService;
        $this->commentService = $commentService;
    }
    public function getPublicList($lat,$lon,$page,$limit = 10)
    {
        $config = $this->configRepository->getByK("SEARCH_DISTANCE");//处理距离数据
        $distanceArr = myExplodeNumbers($config);
        $qb = $this->createQueryBuilder("A");
        $qb->select("A");
        $qb->join("App:UserAddress","B","with","A.address = B");
        $qb->where("A.type = 1");//1=自己创建的订单，2=购买服务创建的订单

        //地理位置筛选
        $km = calcLatLonFromDistance($distanceArr[0]);
        $qb->where("B.lat < ".($lat + $km))
            ->andWhere("B.lat > ".($lat - $km))
            ->andWhere("B.lon < ".($lon + $km))
            ->andWhere("B.lon > ".($lon - $km));
        //地理位置排序
        $qb->addSelect("SQRT(($lat - B.lat)*($lat - B.lat) + ($lon  - B.lon)*($lon  - B.lon)) AS distance");
        $qb->orderBy("SQRT(($lat - B.lat)*($lat - B.lat) + ($lon  - B.lon)*($lon  - B.lon))","ASC");

        $qb->setMaxResults($limit);
        $qb->setFirstResult($page * $limit - $limit);
        $data = $qb->getQuery()->execute();
    }
    public function dealWithTaskCreate(Task $task)
    {
        //1类目优先
        $cat1 = $task->getCat1();//todo 暂时先不匹配父栏目
        $cat2 = $task->getCat2();
        //---检查子栏目下数量过少再给到父栏目//todo 暂时先不这么设计了，只检查子栏目
        $qb = $this->_em->createQueryBuilder();
        $qb->from("App:Shop","Shop");
        $qb->innerJoin("Shop.categories","Cat","with","Cat = ".$cat2->getId());
        $qb->select("count(Shop.id) as num");


//        $qb->groupBy("Shop.id");
//        $qb->addGroupBy("Cat");
        //地理位置优先于区县设置
        $qb->where("Shop.city = '".$task->getAddress()->getCity()."'");

        //获取用户的地址区域

        $data = $qb->getQuery()->execute();
        $numCat1 = $data[0]["num"];
        var_dump($data);
    }
    public function dealWithTaskConfirm(Task $task,$content="",$score=5,$isUserPost = 1)
    {
        $this->_em->beginTransaction();
        try {
            $user = $task->getUser();
            //修改任务状态
            $task->setStatus(900)
                ->setConfirmAt(new \DateTime())
                ->setFinishAt(new \DateTime());

            //修改订单状态
            $orders = $task->getOrders();
            $orders->setStatus(300);
            //保存评价信息
            //根据评价打分计算
            $this->commentService->add2Shop($user,$orders->getSeller()->getShop()->getId(),$content,$score);

            //todo 确认订单需要分配金额
            //--佣金比例
            $cut_all = $this->configRepository->getByK("INCOME_PLAT_CUT");//10%
            $cut_plat = $cut_all;
            $cut = 100-$cut_all;
            //--活动减免
            $back_activity = $this->configRepository->getByK("INCOME_BACK_ACTIVITY");
            $cut+=(float)$back_activity;
            $cut_plat-=(float)$back_activity;
            //--保证金用户减免
            $back_insure = $this->configRepository->getByK("INCOME_BACK_INSURE");
            $shop = $orders->getSeller()->getShop();
            if ($this->shopService->hasTag($shop,ShopService::__TAG_INSURE__)) {
                $cut+=(float)$back_insure;
                $cut_plat-=(float)$back_insure;
            }
            //--主动评价减免
            $back_comment = $this->configRepository->getByK("INCOME_BACK_COMMENT");
            if ($isUserPost) {
                $cut+=(float)$back_comment;
                $cut_plat-=(float)$back_comment;
            }
            //--等级减免。todo

            //计算最终的佣金扣除数量
            $moneyIncome = round($orders->getPayReal() * $cut / 100,3);
            //增加用户收益
            $this->moneyService->mod($orders->getSeller(),$moneyIncome,MoneyService::__MONEY_XIAN_JIN__,130,"任务订单收入",array("order"=>$orders->getId()));
            //创建公告
            $this->announceService->dealWithTaskConfirm($orders->getSeller(),$moneyIncome);

            //推荐人奖励
            $bonus = $this->configRepository->getByK("INVITE_BONUS_ORDER");
            $bonus_percent = $this->configRepository->getByK("INVITE_BONUS_PERCENT");
            $percent = myExplodeNumbers($bonus_percent);
            $bonusMoney = round($orders->getPayReal() * $bonus / 100,3);
            $curUser = $orders->getBuyer();
            $total = array_sum($percent);
            foreach ($percent as $num) {
                $parent = $curUser->getParent();
                if ($parent) {
                    $this->moneyService->mod($parent,round($bonusMoney*($num/$total),2)
                        ,MoneyService::__MONEY_XIAN_JIN__
                        ,171,"佣金：{$orders->getSn()}",array("order"=>$orders->getId()));
                    $curUser = $parent;

                    $cut_plat-=(float)($bonus*($num/$total));
                }else{
                    break;
                }
            }

            //地区代理返佣扣费
            $provinceRate = $this->configRepository->getByK("AGENT_PROVINCE_RATE");
            $cityRate = $this->configRepository->getByK("AGENT_CITY_RATE");
            $areaRate = $this->configRepository->getByK("AGENT_AREA_RATE");
            $cut_plat-=(float)$provinceRate;
            $cut_plat-=(float)$cityRate;
            $cut_plat-=(float)$areaRate;
            //-----省级代理收益
            $this->moneyService->addAgentIncome(
                (float)$orders->getPayReal() * $provinceRate / 100
                , $orders->getId()
                ,$orders->getAddress()->getProvince()
                ,""
                ,""
            );
            //-----市级代理收益
            $this->moneyService->addAgentIncome(
                (float)$orders->getPayReal() * $cityRate / 100
                , $orders->getId()
                ,""
                ,$orders->getAddress()->getCity()
                ,""
            );
            //-----县区级代理收益
            $this->moneyService->addAgentIncome(
                (float)$orders->getPayReal() * $areaRate / 100
                , $orders->getId()
                ,""
                ,""
                ,$orders->getAddress()->getArea()
            );


            //分红池金额增加
            $poolRate = $this->configRepository->getByK("BONUS_POOL_RATE");
            $cut_plat-=(float)$poolRate;
            $this->moneyService->addBonusPool(
                (float)$orders->getPayReal() * $poolRate / 100
                , $orders->getId());

            //计算平台最终的收益
            $this->moneyService->addPlatIncome(
                (float)$orders->getPayReal() * $cut_plat / 100
                , $orders->getId());

            //修改订单状态
            $orders->setStatus(600);
            $this->_em->persist($task);
            $this->_em->persist($orders);

            $this->_em->flush();
        } catch (\Exception $exception) {
            $this->_em->rollback();
            throw $exception;
        }
        $this->_em->commit();
    }

}